//
//  MFAPMScreenShotMonitor.m
//  MFAPMManager
//
//  Created by zhang liyu on 2019/5/26.
//

#import "MFAPMScreenShotMonitor.h"

#import "MFAPMScreenShotMonitorModel.h"
#import "MFAPMNetAOPProtocol.h"
#import "MFAPMUploadManager.h"
#import "MFAPMUtility.h"
#import "MFAPMManager.h"
#import "MFAPMConfig.h"
#import "MFAPMDefine.h"
#import <pthread.h>

@interface MFAPMScreenShotMonitor()<MFAPMNetAOPProtocol>

@property (nonatomic, strong) NSMutableArray<MFAPMScreenShotRequestModel *> *screenShotRequestItemsArr;
@property (nonatomic, assign) pthread_mutex_t lock;

@end

@implementation MFAPMScreenShotMonitor

#pragma mark - Singleton

+ (instancetype)sharedInstance{
    static MFAPMScreenShotMonitor *screenShotMonitor = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        screenShotMonitor = [[MFAPMScreenShotMonitor alloc] init];
    });
    return screenShotMonitor;
}

#pragma mark - Life Circle

- (instancetype)init{
    self = [super init];
    if(self){
        [self configActions];
    }
    return self;
}

- (void)configActions{
    pthread_mutex_init(self.mutexLock, NULL);
}

#pragma mark - Monitor Control Actions

- (void)startMonitor{
    //截屏监听
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(userTakeScreenshot:) name:UIApplicationUserDidTakeScreenshotNotification object:nil];
}

- (void)stopMonitor{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

#pragma mark - ScreenShot Actions

- (void)userTakeScreenshot:(NSNotification *)notification{
    //主线程获取当前截图数据
    __weak typeof(&*self) weakSelf = self;
    [MFAPMUtility dispatchAsyncOnMainThread:^{
        __strong typeof(&*self) strongSelf = weakSelf;
        //截屏图片数据
        NSData *imgData = [MFAPMUtility imageDataWithScreenshot];
        NSString *topVCName = strongSelf.topVCName;
        
        //最后要上传的screenshotModel
        MFAPMScreenShotMonitorModel *monitorModel = [[MFAPMScreenShotMonitorModel alloc] init];
        monitorModel.file = [imgData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength] ? : @"";
        //将图片数据转换为JSON字符串
        monitorModel.file = [MFAPMUtility convertJSONStringFromString:monitorModel.file];
        monitorModel.vc = [topVCName copy];
        //更新request数组
        for (int i = 0; i < strongSelf.screenShotRequestItemsArr.count; i++){
            MFAPMScreenShotRequestModel *itemModel = strongSelf.screenShotRequestItemsArr[i];
            if([itemModel.topVCName isEqualToString:topVCName]){
                [monitorModel.request addObject:itemModel.requestModel];
            }
        }
        //移除缓存的请求model
        pthread_mutex_lock(strongSelf.mutexLock);
        [strongSelf.screenShotRequestItemsArr removeAllObjects];
        pthread_mutex_unlock(strongSelf.mutexLock);
        
        //进行截屏事件的上传操作
        [MFAPMUploadManager cacheItem:monitorModel];
    }];
}

#pragma mark - Net Monitor AOP Delegate Actions

- (void)startLoading:(MFAPMNetMonitorModel *)netMonitorModel{
    NSArray *whiteHostArr = [[MFAPMManager sharedManager].config fetchScreenShotInterceptors];
    if (whiteHostArr.count > 0) {
        NSString *forepart = [NSString stringWithFormat:@"%@://%@", netMonitorModel.request.URL.scheme, netMonitorModel.request.URL.host];
        if([whiteHostArr containsObject:forepart]){
            [self updateScreenShotRequestItemWithNetModel:netMonitorModel];
        }
        return;
    }
    [self updateScreenShotRequestItemWithNetModel:netMonitorModel];
}

- (void)stopLoading:(MFAPMNetMonitorModel *)netMonitorModel{
}

- (void)updateScreenShotRequestItemWithNetModel:(MFAPMNetMonitorModel *)netModel{
    if(!netModel){
        return;
    }
    //保存model指针，在model更新时不必进行手动更新
    __block MFAPMNetMonitorModel *requestModel = netModel;
    [MFAPMUtility dispatchAsyncOnMainThread:^{
        MFAPMScreenShotRequestModel *screenShotRequestModel = [[MFAPMScreenShotRequestModel alloc] init];
        screenShotRequestModel.requestModel = requestModel;
        screenShotRequestModel.topVCName = self.topVCName;
        [self addScreenShotRequestItem:screenShotRequestModel];
    }];
}

- (void)addScreenShotRequestItem:(MFAPMScreenShotRequestModel *)item{
    if(!item || item.topVCName.length == 0){
        return;
    }
    pthread_mutex_lock(self.mutexLock);
    [self.screenShotRequestItemsArr addObject:item];
    if(self.screenShotRequestItemsArr.count > kMFAPMScreenShotMaxCacheReqeuestNUM){
        [self.screenShotRequestItemsArr removeObjectAtIndex:0];
    }
    pthread_mutex_unlock(self.mutexLock);
}

#pragma mark - Setter & Getter

- (NSMutableArray *)screenShotRequestItemsArr{
    if(!_screenShotRequestItemsArr){
        _screenShotRequestItemsArr = [NSMutableArray arrayWithCapacity:kMFAPMScreenShotMaxCacheReqeuestNUM];
    }
    return _screenShotRequestItemsArr;
}

- (NSString *)topVCName{
    return NSStringFromClass([MFAPMUtility currentTopViewController].class) ? : @"";
}

- (pthread_mutex_t *)mutexLock{
    if(!(&_lock)){
        pthread_mutex_init(&_lock, NULL);
    }
    return &_lock;
}

@end
